package com.yangfei.mystudy1020.activity;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;

import com.yangfei.mystudy1020.R;
import com.yangfei.mystudy1020.utils.DetectThread;

import org.junit.Assert;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class LeakActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_leak);

        View button = findViewById(R.id.async_task);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testWeakRef();
                startAsyncTask();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        checkMemLeak();
    }

    private void checkMemLeak(){
        // 开启一个后台线程，这个线程不要持有activity的应用，不然泄露又说怪这个线程
        Thread detectThread = new DetectThread(this,"detectThread");

        detectThread.start();//开始检查
    }

    @SuppressLint("StaticFieldLeak")
    void startAsyncTask() {
        // This async task is an anonymous class and therefore has a hidden reference to the outer
        // class MainActivity. If the activity gets destroyed before the task finishes (e.g. rotation),
        // the activity instance will leak.
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                // Do some slow work in background
                SystemClock.sleep(5000);
                return null;
            }
        }.execute();
    }

    private void testWeakRef(){
        ReferenceQueue<Object> queue = new ReferenceQueue<>();
        WeakReference<Object> ref = new WeakReference<>(new Object(), queue);

        Assert.assertNotNull(ref.get());

        Object obj = null;
        obj = queue.poll();

        Assert.assertNull(obj);

        System.gc();

        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        obj = queue.poll();
        Assert.assertNotNull(obj);
    }
}
